#include "ui_calendar.h"
#include "ui_manager.h"

#include "util/timer.h"		    // Needs to come in early
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timeanddate.h"

#include "lang/lang.h"
#include "font/font_manager.h"

#include "script/scripthelper.h"
#include "script/write_lua.h"
#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif // _ENABLE_LUABIND
using namespace ui;
using namespace script;

//UICalendar: Common routines
//======================================================================================================================


UICalendar::UICalendar(UIWidget* pParent,const std::string& Name) :
	UIWidget(pParent, Name)
{
	m_DrawExtraFunc = NULL;
	m_WeeksCount = 4;
	int CurDay = util::TimeAndDate::CurLocalDay(); 
	SetBounds(CurDay-60, CurDay+30,false);
	m_Type = WT_CALENDAR;
}

UICalendar::~UICalendar()
{

}


bool		UICalendar::Create(const std::string& Name, const math::Vec2& Pos, const math::Vec2& Size)
{
	UIWidget::Create(Name, Pos, Size);
	// create progress stuff

	return true;
}


bool		UICalendar::Load(LuaPlus::LuaObject& _LObj)
{
	UIWidget::Load(_LObj);	// get all the common stuff loaded


	//weeks count
	m_WeeksCount = ScriptHelper::GetTableInt(_LObj, "WeeksCount", 4); 

	//images loading

	std::string ImageFile = ScriptHelper::GetTableString(_LObj, "WeekDayCellImage");

	if (ImageFile != "")
		m_SpriteWeekDayCell.SetupSprite(ImageFile);

	ImageFile = ScriptHelper::GetTableString(_LObj, "EvenMonthCellImage");

	if (ImageFile != "")
		m_SpriteEvenMonthCell.SetupSprite(ImageFile);

	ImageFile = ScriptHelper::GetTableString(_LObj, "OddMonthCellImage");

	if (ImageFile != "")
		m_SpriteOddMonthCell.SetupSprite(ImageFile);

	ImageFile = ScriptHelper::GetTableString(_LObj, "CurDayHightlightImage");

	if (ImageFile != "")
		m_SpriteCurDayHightlight.SetupSprite(ImageFile);



	//std::string	 Button = ScriptHelper::GetTableString(_LObj, "SliderIcon", "");

	//float Progress = ScriptHelper::GetTableFloat(_LObj, "SliderValue", 0.0f);
	//SetSlider(Progress);
//	m_SliderSize  = ScriptHelper::GetTableVec2(_LObj, "SliderSize", math::Vec2(m_Size.y, m_Size.y));

	//if (!Button.empty())
	//{
	//		m_ImageA[WI_BUTTON].Create(	Button, m_BaseUV1, m_BaseUV2, false);
	//		m_ImageA[WI_BUTTON].Tick(0);
	//}
	//m_SliderSize  = m_ImageA[WI_BUTTON].m_Size;
	return true;
}



//UICalendar: Tick and Render
//======================================================================================================================

bool		UICalendar::Tick(float dt)
{

	UIWidget::Tick(dt);	// tick children, etc



	return true;
}



bool		UICalendar::Render(bool Force)
{
	if (!UIWidget::Render(Force)) return false;


	int i;
	int x,y;
	int CurDay;
	
	math::Vec2 Size;
	math::Vec2 Position;

	Font* pCurFont = m_Text.GetFont();

	//1. cells

	for (i = 0; i < m_WeeksCount * 7; i++)
	{
		CurDay = m_FirstDay + m_CurOffset + i;

		x = i % 7;
		y = i / 7;

		GetCellCoords(x, y+1, Position, Size);

		int CurMonth = util::TimeAndDate::LocalDayGetMonth(CurDay);

		m_SpriteEvenMonthCell.SetVisible(false);
		m_SpriteOddMonthCell.SetVisible(false);

		if (CurMonth%2 == 0)
		{
			m_SpriteEvenMonthCell.SetVisible(true);
			m_SpriteEvenMonthCell.Quad_SetupCentered(Position + Size * 0.5f, Size * 0.5f);
			m_SpriteEvenMonthCell.SetColor(m_Color);
			m_SpriteEvenMonthCell.Render();
		}
		else
		{
			m_SpriteOddMonthCell.SetVisible(true);
			m_SpriteOddMonthCell.Quad_SetupCentered(Position + Size * 0.5f, Size * 0.5f);
			m_SpriteOddMonthCell.SetColor(m_Color);
			m_SpriteOddMonthCell.Render();
		}

		//cell number

		std::string DayNumber;
		DayNumber = "";
		DayNumber.append(lang::Lang::FormatNumber(util::TimeAndDate::LocalDayGetDayOfMonth(CurDay))); 

		FontManager::Instance().SetColor(ColorRGBA(255,255,255,175));
		FontManager::Instance().PrintCentered(pCurFont, Position + Size * 0.5f, DayNumber.c_str());

	}

	//3. cur day highlight
	CurDay = util::TimeAndDate::CurLocalDay() - m_FirstDay - m_CurOffset;
	m_SpriteCurDayHightlight.SetVisible(false); 

	if (CurDay >= 0 && CurDay < m_WeeksCount * 7)
	{
		GetCellCoords(CurDay % 7, (CurDay / 7) + 1, Position, Size);
		m_SpriteCurDayHightlight.SetVisible(true);
		m_SpriteCurDayHightlight.Quad_SetupCentered(Position + Size * 0.5f, Size * 0.5f);
		m_SpriteCurDayHightlight.SetColor(m_Color);
		m_SpriteCurDayHightlight.Render();
	}

	//4. extra marks
	for (i = 0; i < m_WeeksCount * 7; i++)
	{
		CurDay = m_FirstDay + m_CurOffset + i;

		x = i % 7;
		y = i / 7;

		GetCellCoords(x, y+1, Position, Size);

		if (m_DrawExtraFunc != NULL)
			m_DrawExtraFunc(Position, Size, CurDay);

	}


	FontManager::Instance().RenderCache(); 

	//5. week days
	for (i = 0; i <  7; i++)
	{

		GetCellCoords(i, 0, Position, Size);

		m_SpriteWeekDayCell.SetVisible(true);
		m_SpriteWeekDayCell.Quad_SetupCentered(Position + Size * 0.5f, Size * 0.5f);
		m_SpriteWeekDayCell.SetColor(m_Color);
		m_SpriteWeekDayCell.Render();

		//week day text
		m_WeekDaysText[i].SetExtents(Position, Size);
		m_WeekDaysText[i].Render(); 

	}

	FontManager::Instance().RenderCache(); 


	return true;
}


//UICalendar: Specific methods
//======================================================================================================================

void UICalendar::SetBounds(int FirstDay, int LastDay, bool SundayIsFirst)
{
	m_FirstDay = util::TimeAndDate::WeekGetFirstDay(FirstDay, SundayIsFirst);

	m_LastDay = util::TimeAndDate::WeekGetFirstDay(LastDay, SundayIsFirst);

	if ((((m_LastDay - m_FirstDay) / 7)+1) < m_WeeksCount)
		m_LastDay = m_FirstDay + ((m_WeeksCount-1) * 7); 

	m_CurOffset = util::TimeAndDate::WeekGetFirstDay(util::TimeAndDate::CurLocalDay(), SundayIsFirst);

	m_CurOffset = m_CurOffset - m_FirstDay;

	m_CurOffset = (m_CurOffset) - ((m_WeeksCount-1) * 7);

	if (m_CurOffset < 0)
		m_CurOffset = 0;

	int i;

	for (i = 0; i < 7; i++)
	{
		m_WeekDaysText[i].SetColor(m_Text.GetColor());
		m_WeekDaysText[i].SetFont(m_Text.GetFontName());
		m_WeekDaysText[i].SetVertJust(UIText::TJV_CENTER);
		m_WeekDaysText[i].SetHorizJust(UIText::TJH_CENTER);
		m_WeekDaysText[i].SetCanEdit(false);
		m_WeekDaysText[i].SetOwner(this);
	}

	if (SundayIsFirst == true)
	{
		m_WeekDaysText[0].SetText(lang::Lang::ConvertAtoW("WEEKDAY_SUNDAY"));
		m_WeekDaysText[1].SetText(lang::Lang::ConvertAtoW("WEEKDAY_MONDAY"));
		m_WeekDaysText[2].SetText(lang::Lang::ConvertAtoW("WEEKDAY_TUESDAY"));
		m_WeekDaysText[3].SetText(lang::Lang::ConvertAtoW("WEEKDAY_WEDNESDAY"));
		m_WeekDaysText[4].SetText(lang::Lang::ConvertAtoW("WEEKDAY_THURSDAY"));
		m_WeekDaysText[5].SetText(lang::Lang::ConvertAtoW("WEEKDAY_FRIDAY"));
		m_WeekDaysText[6].SetText(lang::Lang::ConvertAtoW("WEEKDAY_SATURDAY"));

	}
	else
	{

		m_WeekDaysText[0].SetText(lang::Lang::ConvertAtoW("WEEKDAY_MONDAY"));
		m_WeekDaysText[1].SetText(lang::Lang::ConvertAtoW("WEEKDAY_TUESDAY"));
		m_WeekDaysText[2].SetText(lang::Lang::ConvertAtoW("WEEKDAY_WEDNESDAY"));
		m_WeekDaysText[3].SetText(lang::Lang::ConvertAtoW("WEEKDAY_THURSDAY"));
		m_WeekDaysText[4].SetText(lang::Lang::ConvertAtoW("WEEKDAY_FRIDAY"));
		m_WeekDaysText[5].SetText(lang::Lang::ConvertAtoW("WEEKDAY_SATURDAY"));
		m_WeekDaysText[6].SetText(lang::Lang::ConvertAtoW("WEEKDAY_SUNDAY"));

	}
}


bool UICalendar::CanScrollUp()
{
	return m_CurOffset > (SCROLL_VALUE-1);
}

bool UICalendar::CanScrollDown()
{
	return (m_CurOffset + m_FirstDay + (m_WeeksCount-1)*SCROLL_VALUE) < m_LastDay;
}

void UICalendar::ScrollDown()
{

	//if (m_CurOffset + m_FirstDay + (m_WeeksCount-1)*7 < m_LastDay)
	if (CanScrollDown())
		m_CurOffset += SCROLL_VALUE;
}



void UICalendar::ScrollUp()
{

	//if (m_CurOffset > 6)
	if (CanScrollUp())
		m_CurOffset -= SCROLL_VALUE;
}



void UICalendar::SetDrawExtraFunc(CalendarDrawExtraFunc FuncPtr)
{
	m_DrawExtraFunc = FuncPtr;

}



int UICalendar::GetFirstShownDay()
{
	return m_FirstDay + m_CurOffset;
}



int UICalendar::GetLastShownDay()
{
	return m_FirstDay + m_CurOffset + m_WeeksCount * 7 - 1;
}



//UICalendar: Helper methods
//======================================================================================================================

void UICalendar::GetCellCoords(int x, int y, math::Vec2& Position, math::Vec2& Size)
{

	Size.x = m_Size.x / 7.0f;
	Size.y = m_Size.y / float(m_WeeksCount + 1);

	Position.x = m_Pos.x + Size.x * float(x);

	Position.y = m_Pos.y + Size.y * float(y);

}//void UICalendar::GetCellCoords(int x, int y, math::Vec2& Position, math::Vec2& Size)



void	UICalendar::RefreshFonts()
{
	UIWidget::RefreshFonts();
	for (int i=0; i<WEEK_DAYS; i++) 
		m_WeekDaysText[i].SetFont(m_WeekDaysText[i].GetFontName());
}






/// register with LUA Bind
void	UICalendar::Register(LuaPlus::LuaState* _pScript)
{
#ifdef _ENABLE_LUABIND

	
#endif // _ENABLE_LUABIND
}








